/**
 * @Author: Caven
 * @Date: 2020-01-15 20:27:27
 */
import * as Cesium from "cesium"
import BaiduMercatorTilingScheme from './BaiduMercatorTilingScheme'

const TILE_URL = {
  img:
    '//shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46',
  vec:
    '//online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=sl&v=020',
  custom:
    '//api{s}.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&scale=1&customid={style}',
  traffic:
    '//its.map.baidu.com:8002/traffic/TrafficTileService?time={time}&label={labelStyle}&v=016&level={z}&x={x}&y={y}&scaler=2'
}
class BaiduImageryProvider {
  constructor(options: {[name: string]: any} = {}) {
    (this as any)._url =
      options.url ||
      [
        options.protocol || '',
        (TILE_URL as any)[options.style] || TILE_URL['custom']
      ].join('');
    (this as any)._tileWidth = 256;
    (this as any)._tileHeight = 256;
    (this as any)._maximumLevel = 18;
    (this as any)._crs = options.crs || 'BD09'
    if (options.crs === 'WGS84') {
      let resolutions: any[] = [];
      for (let i = 0; i < 19; i++) {
        resolutions[i] = 256 * Math.pow(2, 18 - i)
      }
      (this as any)._tilingScheme = new BaiduMercatorTilingScheme({
        resolutions,
        rectangleSouthwestInMeters: new Cesium.Cartesian2(
          -20037726.37,
          -12474104.17
        ),
        rectangleNortheastInMeters: new Cesium.Cartesian2(
          20037726.37,
          12474104.17
        )
      })
    } else {
      (this as any)._tilingScheme = new Cesium.WebMercatorTilingScheme({
        rectangleSouthwestInMeters: new Cesium.Cartesian2(-33554054, -33746824),
        rectangleNortheastInMeters: new Cesium.Cartesian2(33554054, 33746824)
      })
    }
    (this as any)._rectangle = (this as any)._tilingScheme.rectangle;
    (this as any)._credit = undefined;
    (this as any)._style = options.style || 'normal';
    (this as any)._errorEvent = new Cesium.Event();
  }

  get url() {
    return (this as any)._url
  }

  get token() {
    return (this as any)._token
  }

  get tileWidth() {
    if (!this.ready) {
      throw new Cesium.DeveloperError(
        'tileWidth must not be called before the imagery provider is ready.'
      )
    }
    return (this as any)._tileWidth
  }

  get tileHeight() {
    if (!this.ready) {
      throw new Cesium.DeveloperError(
        'tileHeight must not be called before the imagery provider is ready.'
      )
    }
    return (this as any)._tileHeight
  }

  get maximumLevel() {
    if (!this.ready) {
      throw new Cesium.DeveloperError(
        'maximumLevel must not be called before the imagery provider is ready.'
      )
    }
    return (this as any)._maximumLevel
  }

  get minimumLevel() {
    if (!this.ready) {
      throw new Cesium.DeveloperError(
        'minimumLevel must not be called before the imagery provider is ready.'
      )
    }
    return 0
  }

  get tilingScheme() {
    if (!this.ready) {
      throw new Cesium.DeveloperError(
        'tilingScheme must not be called before the imagery provider is ready.'
      )
    }
    return (this as any)._tilingScheme
  }

  get rectangle() {
    if (!this.ready) {
      throw new Cesium.DeveloperError(
        'rectangle must not be called before the imagery provider is ready.'
      )
    }
    return (this as any)._rectangle
  }

  get ready() {
    return !!(this as any)._url
  }

  get errorEvent() {
    return (this as any)._errorEvent
  }

  get credit() {
    return (this as any)._credit
  }

  get hasAlphaChannel() {
    return true
  }

  getTileCredits(x: any, y: any, level: any) {}

  requestImage(x: number, y: number, level: any) {
    if (!this.ready) {
      throw new Cesium.DeveloperError(
        'requestImage must not be called before the imagery provider is ready.'
      )
    }
    let xTiles = (this as any)._tilingScheme.getNumberOfXTilesAtLevel(level)
    let yTiles = (this as any)._tilingScheme.getNumberOfYTilesAtLevel(level)
    let url = (this as any)._url
      .replace('{z}', level)
      .replace('{s}', String(1))
      .replace('{style}', (this as any)._style)
    if ((this as any)._crs === 'WGS84') {
      url = url.replace('{x}', String(x)).replace('{y}', String(-y))
    } else {
      url = url
        .replace('{x}', String(x - xTiles / 2))
        .replace('{y}', String(yTiles / 2 - y - 1))
    }
    return Cesium.ImageryProvider.loadImage((this as any), url)
  }
}

export default BaiduImageryProvider
